<template>
  <a-modal :width="width" ref="modalRef" wrapClassName="draggable-modal" centered :open="open" @cancel="onCancel"
    :maskClosable="false" :footer="null">
    <!-- title 区域用于点击拖拽 -->
    <template #title>
      <div ref="modalTitleRef" class="title">{{ title }}</div>
    </template>

    <div class="modal-content" ref="containerRef">
      <a-spin :spinning="isLoading">
        <a-flex vertical :gap="30" class="affix-title">
          <a-row :gutter="20" class="form-row">
            <a-col :span="3" style="text-align: center">字段名</a-col>
            <a-col :span="3" style="text-align: center">显示名</a-col>
            <a-col :span="2">是否校验</a-col>
            <a-col :span="2">是否必填</a-col>
            <a-col :span="3" style="text-align: center">校验方法</a-col>
            <a-col :span="3">校验规则</a-col>
            <a-col :span="6" style="text-align: center">错误提示</a-col>
          </a-row>
        </a-flex>
        <!-- 站位元素，避免底部元素被遮挡 -->
        <div class="affix-title-positioning"></div>

        <a-form ref="formRef" :model="formRows" :rules="formRules">
          <a-flex vertical :gap="30" v-for="(row, index) in formRows" :key="`form-row-${index}`">
            <!-- TODO: 需要增加行就复制外部的 a-row -->
            <a-row :gutter="20" class="form-row">
              <!-- 左边的 label 列， span 占据了 4 个格子（一行被分割为24格） -->
              <a-col :span="3">
                <!-- 内部布局，左右 上下 间距10px， wrap 效果：当一行的元素超过24格时，会自动换行 -->
                <a-row :gutter="[0, 10]" wrap>
                  <a-col :span="24" style="text-align: center">{{ row.field_name }}</a-col>
                </a-row>
              </a-col>
              <!-- 右边的 表单 列， span 占据了 20 个格子（一行被分割为24格 -->
              <a-col :span="21">
                <!-- 内部布局，左右 上下 间距10px， wrap 效果：当一行的元素超过24格时，会自动换行 -->
                <a-row :gutter="[10, 10]" wrap>
                  <a-col :span="3">
                    <a-form-item label="" :name="[index, 'field_display_name']">
                      <a-input v-model:value.trim="row.field_display_name" />
                    </a-form-item>
                  </a-col>
                  <a-col :span="3">
                    <a-form-item label="" :name="[index, 'is_check']">
                      <a-switch v-model:checked="row.is_check" checked-children="关闭校验" un-checked-children="开启校验"
                        :checked-value="1" :un-checked-value="2" />
                    </a-form-item>
                  </a-col>
                  <a-col :span="2">
                    <a-form-item label="" :name="[index, 'is_required']">
                      <a-switch v-model:checked="row.is_required" checked-children="非必填" un-checked-children="必填"
                        :checked-value="1" :un-checked-value="2" />
                    </a-form-item>
                  </a-col>
                  <a-col :span="3">
                    <a-form-item label="" :name="[index, 'check_method']">
                      <a-select v-model:value="row.check_method" :options="[
                        { value: '1', label: '字符串' },
                        { value: '2', label: '整数' },
                        { value: '3', label: '集合值' },
                        { value: '4', label: '手机号' },
                        { value: '5', label: '邮箱' },
                      ]" />
                    </a-form-item>
                  </a-col>
                  <a-col :span="3">
                    <a-form-item label="" :name="[index, 'check_rules_value']">
                      <a-input v-model:value.trim="row.check_rules_value" />
                    </a-form-item>
                  </a-col>
                  <a-col :span="10">
                    <a-form-item label="" :name="[index, 'hint_des']">
                      <a-input v-model:value.trim="row.hint_des" />
                    </a-form-item>
                  </a-col>
                  <a-col :span="24">
                    <a-form-item label="字段备注：" :name="[index, 'remarks']">
                      <a-input v-model:value.trim="row.remarks" />
                    </a-form-item>
                  </a-col>
                </a-row>
              </a-col>
            </a-row>
          </a-flex>
        </a-form>
      </a-spin>
    </div>

    <!-- 表单按钮 -->
    <div class="modal-footer">
      <a-form-item class="form-item-buttons">
        <a-flex justify="center" :gap="16">
          <a-button type="primary" htmlType="submit" @click="onFinish">确定</a-button>
          <a-button @click="onCancel">取消</a-button>
        </a-flex>
      </a-form-item>
    </div>

    <!-- 自定义渲染 实现拖拽效果 -->
    <template #modalRender="{ originVNode }">
      <div :style="transformStyle">
        <component :is="originVNode" />
      </div>
    </template>
  </a-modal>
</template>
<script setup lang="ts">
  import { ref, reactive, computed, watch, watchEffect, type CSSProperties } from 'vue';
  import { useDraggable } from '@vueuse/core';
  import { message } from 'ant-design-vue';
  import { bizApi } from '@/api/biz';
  const containerRef = ref()
  const width = 1200;
  const formRef = ref();
  const isLoading = ref(false);

  const title = ref("字段配置");
  const open = ref(false);//控制弹窗显示、隐藏 变量

  const table_config_id = ref(0);//要编辑的数据ID

  /* 弹窗显示 */
  function show(id: number, table_name: string, table_display_name: string) {
    table_config_id.value = id;
    title.value = table_display_name + "(" + table_name + ") 字段配置";
    open.value = true;
  }
  /* 弹窗关闭 */
  function onCancel() {
    open.value = false;
  }

  // 定义单行表单数据类型
  interface FormRow {
    id: number;
    table_config_id: number;
    field_name: string;
    field_display_name: string;
    field_type: string;
    field_length: number;
    is_check: number; // 开启校验
    is_required: number; // 必填/非必填
    check_method: Record<string, any>;   // 校验规则
    check_rules_value: string;   // 规则值
    hint_des: string;   // 校验提示
    remarks: string;   // 校验提示
  }
  // 初始化：至少保留一行数据
  const formRows = reactive<FormRow[]>([]);

  /* 获取字段配置列表 参数 */
  const getAction = "base.manage.fieldconfig.ServiceImpl.list";
  const getParams = computed(() => ({
    "table_config_id": table_config_id.value,
  }));

  /* 监听 props.open = true 时，调用 onOpen 方法 并传递 recordId */
  watch(() => open.value, (val) => {
    if (val === true) {
      console.log('table_config_id=', table_config_id.value);
      getDataInfo(getAction, getParams);
    }
  });

  /* 数据服务请求（访问服务端接口获取数据） */
  async function getDataInfo(action: string, params: Record<string, any>) {
    isLoading.value = true;
    try {
      const result = await bizApi.httpList(action, params.value);
      formRows.length = 0;
      if (Array.isArray(result) && result.length > 0) {
        result.forEach(row => {
          formRows.push({
            ...row,
            is_check: [1, 2].includes(row.is_check) ? row.is_check : 2,
            is_required: [1, 2].includes(row.is_required) ? row.is_required : 2,
          })
        })
      }
      //console.log("result",result)
      //Object.assign(formRows, result);
      isLoading.value = false;
    } catch (error: any) { }
    isLoading.value = false;
    return false;
  }

  const formRules = reactive<any>({});
  /* 弹窗 保存 事件，仅通知调用组件 */
  const onFinish = async () => {
    try {
      const formValues = await formRef.value.validateFields();
      //console.log("表单校验后的键值对",formValues)

      // 2. 转换为数组格式（与 formRows 结构一致）
      const fields = Object.keys(formValues).map(indexStr => {
        const index = Number(indexStr); // 动态行索引
        const rowValues = formValues[indexStr]; // 该行的所有字段值
        return {
          ...formRows[index], // 保留原始数据（如 id、field_name 等不可编辑字段）
          ...rowValues        // 覆盖表单编辑后的值
        } as FormRow;
      });
      // 3. 合并参数：getParams（table_config_id） + 表单数组（fields）
      const submitData = {
        table_config_id: getParams.value.table_config_id, // 从查询参数获取
        fields: fields // 表单数组
      };
      //console.log("合并后提交参数：", submitData);
      const ret = await postFormData(postAction.value, submitData);
      if (ret) {
        onCancel();
      }
      //console.log("返回结果：", ret);
    } catch (error) {
      return;
    }
  };

  const postAction = ref('base.manage.fieldconfig.ServiceImpl.update');

  /* 数据服务请求（访问服务端接口获取数据） */
  async function postFormData(action: string, params: Record<string, any>): Promise<boolean> {
    isLoading.value = true;
    try {
      //await formRef.value.validate();
      try {
        const result = await bizApi.httpSave(action, params);
        isLoading.value = false;
        message.success({
          // content: result.sub_message || '数据保存成功',
          content: '数据保存成功',
        });
        return true;
      } catch (error: any) {
        console.log(error);
        isLoading.value = false;
        return Promise.reject(error);
      }
    } catch (error) { }
    isLoading.value = false;
    return false;
  }


  /* ----------------------- 暴露方法给父组件 ------------------------ */
  defineExpose({
    show
  });

  /* ----------------------- 拖拽逻辑代码 ----------------------- */
  const modalTitleRef = ref();
  const { x, y, isDragging } = useDraggable(modalTitleRef);

  // 拖拽起始位置
  const startX = ref(0);
  const startY = ref(0);
  const startedDrag = ref(false);

  // 当前变换的坐标
  const transformX = ref(0);
  const transformY = ref(0);

  // 拖拽前的变换坐标
  const preTransformX = ref(0);
  const preTransformY = ref(0);

  // 拖拽区域的边界矩形
  const dragRect = ref({ left: 0, right: 0, top: 0, bottom: 0 });

  // 监听x、y坐标变化，更新拖拽起始位置和边界信息
  watch([x, y], () => {
    if (!startedDrag.value) {
      startX.value = x.value;
      startY.value = y.value;

      const bodyRect = document.body.getBoundingClientRect();
      const titleRect = modalTitleRef.value.getBoundingClientRect();
      dragRect.value.right = bodyRect.width - titleRect.width;
      dragRect.value.bottom = bodyRect.height - titleRect.height;

      preTransformX.value = transformX.value;
      preTransformY.value = transformY.value;
    }
    startedDrag.value = true;
  });
  watch(isDragging, () => {
    if (!isDragging) {
      startedDrag.value = false;
    }
  });

  // 计算拖拽过程中的变换坐标，确保在有效范围内
  watchEffect(() => {
    if (startedDrag.value) {
      transformX.value =
        preTransformX.value + Math.min(Math.max(dragRect.value.left, x.value), dragRect.value.right) - startX.value;
      transformY.value =
        preTransformY.value + Math.min(Math.max(dragRect.value.top, y.value), dragRect.value.bottom) - startY.value;
    }
  });

  // 通过计算样式移动弹窗
  const transformStyle = computed<CSSProperties>(() => {
    return {
      transform: `translate(${transformX.value}px, ${transformY.value}px)`,
    };
  });
</script>
<style lang="less" scoped>
  .modal-content {
    /* 给表单内容加左右内边距，避免贴边 */
    padding: 0 2px;

    :deep(.ant-spin-container) {
      height: 75vh;
      overflow-y: auto;
      overflow-x: hidden;

      .affix-title {
        position: fixed;
        top: 44px;
        height: 42px;
        // 减去弹窗左右边距，减去内部元素的左右边距
        width: calc(100% - 48px - 20px);
        background: #fff;
        z-index: 99;
      }

      .affix-title-positioning {
        height: 42px;
      }
    }

    .ant-col {
      min-height: 32px;
      line-height: 32px;
    }

    .ant-form-item {
      margin-bottom: 0;
    }

    .form-row {
      padding-bottom: 10px;
      border-bottom: 1px dashed #f0f0f0;

      &:last-child {
        border-bottom: none;
      }
    }
  }

  .modal-footer {
    margin-top: 20px;
    padding: 16px 24px;
    border-top: 1px solid #f0f0f0;
  }

  .form-item-buttons {
    margin-top: auto;
  }

  :deep(.ant-modal-content) {
    padding-top: 0;
  }

  .draggable-modal {
    .title {
      position: sticky;
      top: 0;
      padding-top: 20px;
      width: 100%;
      cursor: move;
    }
  }
</style>
